package com.roger.homecenterscreen.voice

import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioManager
import android.media.AudioTrack
import android.util.Log

/**
 * 简单PCM播放器
 * 仅支持 CosyVoice 流式返回的 PCM 16bit 单声道
 */
class CosyAudioPlayer(
    private val sampleRate: Int = 24000
) {
    private val TAG = "CosyAudioPlayer"
    private var audioTrack: AudioTrack? = null
    private var writeExecutor: java.util.concurrent.ExecutorService = java.util.concurrent.Executors.newSingleThreadExecutor()

    fun start() {
        if (audioTrack != null) return
        if (writeExecutor.isShutdown) {
            writeExecutor = java.util.concurrent.Executors.newSingleThreadExecutor()
        }
        val minBuffer = AudioTrack.getMinBufferSize(
            sampleRate,
            AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT
        )
        audioTrack = AudioTrack.Builder()
            .setAudioAttributes(
                AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                    .build()
            )
            .setAudioFormat(
                AudioFormat.Builder()
                    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                    .setSampleRate(sampleRate)
                    .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
                    .build()
            )
            .setTransferMode(AudioTrack.MODE_STREAM)
            .setBufferSizeInBytes(minBuffer)
            .build()
        audioTrack?.play()
        Log.i(TAG, "AudioTrack started, sr=$sampleRate")
    }

    fun writePcm(pcm: ByteArray) {
        val at = audioTrack ?: return
        if (at.playState != AudioTrack.PLAYSTATE_PLAYING) at.play()
        writeExecutor.execute {
            try {
                at.write(pcm, 0, pcm.size, AudioTrack.WRITE_NON_BLOCKING)
            } catch (_: Exception) {}
        }
    }

    fun stop() {
        try {
            audioTrack?.stop()
        } catch (_: Exception) {}
        try {
            audioTrack?.release()
        } catch (_: Exception) {}
        audioTrack = null
        try { writeExecutor.shutdownNow() } catch (_: Exception) {}
        Log.i(TAG, "AudioTrack stopped")
    }
}